package org.dandsoft.blackbox.knowledge;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.Attribute;
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;

import java.util.List;
import java.util.ArrayList;
import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * User: dvilyuzhanin
 * Date: 13.01.2009 19:55:28
 */
public class ImageInfo extends AbstractInfo<ImageInfo> {

    public final static String IMAGE_GROUP_NAME = "images";
    public final static String TYPE = "image";
    private static final DataFormat FORMAT = DataFormat.Xml;

    private static final String IMAGE_ELEMENT = "image";
    private static final String PACKAGE_ELEMENT = "package";
    private static final String NAME_ELEMENT = "name";
    private static final String VERSION_ELEMENT = "version";
    private static final String ENTITIES_ELEMENT = "entities";
    private static final String ENTITY_ELEMENT = "entity";
    private static final String ENTITY_NAME_ATTRIBUTE = "name";
    private static final String ENTITY_QUALITY_ATTRIBUTE = "quality";

    private Version version;

    private List<EntityEntry> entities;


    public ImageInfo() {
        super(IMAGE_GROUP_NAME, TYPE, FORMAT);
    }

    public void add(InfoName entity, Integer quality) {
        if (entities == null) {
            entities = new ArrayList<EntityEntry>();
        }
        EntityEntry entry = new EntityEntry();
        entry.setEntityName(entity);
        entry.setQuality(quality);
        entities.add(entry);
    }

    public void store(OutputStream out) throws IOException {
        Document document = new Document();

        Element rootElement = new Element(IMAGE_ELEMENT);
        document.setRootElement(rootElement);

        XMLUtil.createElement(rootElement, PACKAGE_ELEMENT, getName().getPackageName());
        XMLUtil.createElement(rootElement, NAME_ELEMENT, getName().getName());
        if (version != null) {
            XMLUtil.createElement(rootElement, VERSION_ELEMENT, version.format());
        }

        if (entities != null && entities.size() > 0) {
            Element entitiesElement = XMLUtil.createElement(rootElement, ENTITIES_ELEMENT, null);
            for (EntityEntry entry : entities) {
                Element entryElement = XMLUtil.createElement(entitiesElement, ENTITY_ELEMENT, null,
                                                             new Attribute(ENTITY_NAME_ATTRIBUTE, entry.getEntityName().getFullName()));
                if (entry.getQuality() != null) {
                    entryElement.setAttribute(ENTITY_QUALITY_ATTRIBUTE, entry.getQuality().toString());
                }
            }

        }


        XMLOutputter outputer = new XMLOutputter();
        outputer.output(document, out);

    }


    public void load(InputStream in) throws IOException {
        SAXBuilder builder = new SAXBuilder();
        try {
            Document document = builder.build(in);

            Element rootElement = document.getRootElement();
            XMLUtil.assertElement(rootElement, IMAGE_ELEMENT);

            Element packageElement = rootElement.getChild(PACKAGE_ELEMENT);
            String packageName = null;
            if (packageElement != null) {
                packageName = packageElement.getTextNormalize();
            }

            Element nameElement = rootElement.getChild(NAME_ELEMENT);
            if (nameElement == null) {
                throw new IOException("Image name element not found");
            }

            setName(new InfoName(nameElement.getTextNormalize(), packageName));

            Element versionElement = rootElement.getChild(VERSION_ELEMENT);
            if (versionElement != null) {
                version = new Version(Integer.parseInt(versionElement.getTextNormalize()));
            }

            Element entitiesElement = rootElement.getChild(ENTITIES_ELEMENT);
            if (entitiesElement != null) {

                List entryElements = entitiesElement.getChildren();
                this.entities = new ArrayList<EntityEntry>(entryElements.size());
                for (Object entryElement : entryElements) {
                    Element entityElement = (Element) entryElement;
                    XMLUtil.assertElement(entityElement, ENTITY_ELEMENT);

                    EntityEntry entry = new EntityEntry();
                    entry.setEntityName(new InfoName(entityElement.getAttribute(ENTITY_NAME_ATTRIBUTE).getValue()));
                    if (entityElement.getAttribute(ENTITY_QUALITY_ATTRIBUTE) != null) {
                        entry.setQuality(entityElement.getAttribute(ENTITY_QUALITY_ATTRIBUTE).getIntValue());
                    }
                    this.entities.add(entry);
                }
            }
        } catch (JDOMException e) {
            throw new IOException(e);
        } catch (Exception e) {
            throw new IOException(e);
        }
    }

    public Version getVersion() {
        return version;
    }

    public void setVersion(Version version) {
        this.version = version;
    }


    public List<EntityEntry> getEntities() {
        return entities;
    }

    public void setEntities(List<EntityEntry> entities) {
        this.entities = entities;
    }
}
